﻿using Microsoft.UI;
using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Vanara.PInvoke;
using Windows.ApplicationModel.Store;
using Windows.Graphics;
using Windows.Storage;
using Windows.UI;
using WinRT.Interop;

namespace SerialCommand
{
    internal class MainConfig
    {
        private Color lineColor;
        private BackStyleControl.FastStyle style;
        public Color LineColor { get { return lineColor; } set { lineColor = value; } }
        public BackStyleControl.FastStyle Style { get { return style; } set { style = value; } }
        static private MainConfig current;
        private Window window;
        private AppWindow appWindow;
        private Microsoft.UI.WindowId id;
        private IntPtr hwnd;
        BackStyleControl backStyleControl;
        MainConfig(Object window)
        {
            this.window = (Window)window;
            hwnd = WindowNative.GetWindowHandle(window);
            id = Win32Interop.GetWindowIdFromWindow(hwnd);
            appWindow = AppWindow.GetFromWindowId(id);
        }
        static public MainConfig Current
        {
            get { return current; }
        }
        static public MainConfig GetMainConfig(Object window)
        {
            if (current == null)
            {
                current = new MainConfig(window);
            }
            return current;
        }
        public AppWindow AppWindow { get { return appWindow; } }
        public IntPtr Hwnd { get { return hwnd; } }
        public void ReadConfig()
        {
            if (ApplicationData.Current.LocalSettings.Values["IsMainWindowMaximum"] is true)
            {
                // 最大化
                User32.ShowWindow(hwnd, ShowWindowCommand.SW_SHOWMAXIMIZED);
            }
            if (ApplicationData.Current.LocalSettings.Values["MainWindowRect"] is ulong value)
            {
                var rect = new WindowRect(value);
                // 屏幕区域
                var area = DisplayArea.GetFromWindowId(windowId: id, DisplayAreaFallback.Primary);
                // 若窗口在屏幕范围之内
                if (rect.Left > 0 && rect.Top > 0 && rect.Right < area.WorkArea.Width && rect.Bottom < area.WorkArea.Height)
                {
                    appWindow.MoveAndResize(rect.ToRectInt32());
                }
            }
            if (ApplicationData.Current.LocalSettings.Values["LineColor"] is byte[] color)
            {
                lineColor = Color.FromArgb(color[0], color[1], color[2], color[3]);
            }
            if (ApplicationData.Current.LocalSettings.Values["BackStyle"] is byte StyleEnumNumber)
            {
                BackStyleControl.FastStyle fastStyle = (BackStyleControl.FastStyle)StyleEnumNumber;
                backStyleControl = new BackStyleControl(fastStyle, ref window);
                backStyleControl.SetConfigurationSourceTheme(((FrameworkElement)window.Content).ActualTheme);
            }
            else
            {
                backStyleControl = new BackStyleControl(BackStyleControl.FastStyle.Acrylic, ref window);
                backStyleControl.SetConfigurationSourceTheme(((FrameworkElement)window.Content).ActualTheme);
            }
        }
        public void SaveConfig()
        {
            // 保存窗口状态
            backStyleControl.WindowsColose();
            var wpl = new User32.WINDOWPLACEMENT();
            if (User32.GetWindowPlacement(hwnd, ref wpl))
            {
                ApplicationData.Current.LocalSettings.Values["IsMainWindowMaximum"] = wpl.showCmd == ShowWindowCommand.SW_MAXIMIZE;
                var p = appWindow.Position;
                var s = appWindow.Size;
                var rect = new WindowRect(p.X, p.Y, s.Width, s.Height);
                ApplicationData.Current.LocalSettings.Values["MainWindowRect"] = rect.Value;
                byte[] color = new byte[4];
                color[0] = lineColor.A; color[1] = lineColor.R; color[2] = lineColor.G; color[3] = lineColor.B;
                ApplicationData.Current.LocalSettings.Values["LineColor"] = color;
                ApplicationData.Current.LocalSettings.Values["BackStyle"] = (byte)style;
            }
        }
        public void SetStyle(BackStyleControl.FastStyle fastSytle)
        {
            style = fastSytle;
            backStyleControl.WindowsColose();
            backStyleControl = new BackStyleControl(fastSytle, ref window);
        }
        public BackStyleControl HomeStyle
        {
            get { return backStyleControl; }
        }

        [StructLayout(LayoutKind.Explicit)]
        private struct WindowRect
        {
            [FieldOffset(0)]
            public short X;
            [FieldOffset(2)]
            public short Y;
            [FieldOffset(4)]
            public short Width;
            [FieldOffset(6)]
            public short Height;
            [FieldOffset(0)]
            public ulong Value;

            public int Left => X;
            public int Top => Y;
            public int Right => X + Width;
            public int Bottom => Y + Height;

            public WindowRect(int x, int y, int width, int height)
            {
                Value = 0;
                X = (short)x;
                Y = (short)y;
                Width = (short)width;
                Height = (short)height;
            }

            public WindowRect(ulong value)
            {
                X = Y = Width = Height = 0;
                Value = value;
            }

            public RectInt32 ToRectInt32()
            {
                return new RectInt32(X, Y, Width, Height);
            }
        }
    }
}
